home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
bbskt30a.zip
/
MTASK20.ZIP
/
MTASK.DOC
next >
Wrap
Text File
|
1990-03-12
|
18KB
|
526 lines
.dhMTASK 2.0 by Wayne Conrad
.np Documentation written using Multi-Edit 4.01Pd
.rm 72
.df .ce -.pa-
.tm6
.ceMTASK
MTASK is a unit for Turbo Pascal 5.5, to allow a Turbo Pascal program
to exhibit simple multi-tasking. MTASK gives your program a
non-preemptive, request driven multi-tasking capability. I will
explain what I mean by that later.
MTASK 2.0 was written and donated to the public domain by Wayne E.
Conrad (me) in March of 1990. I may be contact via my BBS,
Pascalaholics Anonymous
(602) 484-9356
300/1200/2400 bps
24 hours/day
or by mail at my home:
10 E Bell Road #1001
Phoenix, AZ 85022
I am interested in any modifications, bug reports, or comments you
have.
If you modify this package, please keep my name and the name of any
other programmers who've worked on it intact. Give credit to yourself,
too! Please distribute the complete package, with documentation and
demonstration programs included.
1.1 INTRODUCTION
MTASK allows your Turbo Pascal program to do simple multi-tasking. I
call MTASK's brand of multi-tasking "non-preemptive, request driven."
Preemptive means that the switch from one task to another can happen at
almost any time. Most preemptive systems have an interrupt driver
hooked to a hardware timer, which causes a task switch every time the
hardware timer goes off. The advantage of this kind of multi-tasking
is that your programs don't have to be written with multi-tasking in
mind, and don't even have to know that its taking place. Also, no
program can hog the system for long, because the interrupt driver
switches from one program to another fairly often. Desqview and
Double-DOS, and OS/2 are operating environments that do preemptive,
interrupt-driven multi-tasking. The disadvantage of this kind of
multi-tasking is that it can be complex to write and difficult in the
extreme to debug. These difficulties are compounded in an MS-DOS
environment because MS-DOS was not meant to be used in a multi-tasking
environment.
On the other hand, non-preemptive multi-tasking only switches tasks at
certain, well defined times. There is no interrupt driver that forces
task switches. In the original Macintosh operating system, for example,
task switches only occured when a task called the operating system. The
advantage of non-preemptive multi-tasking is that it is much simpler to
write and debug than preemptive multi-tasking, because the system has
total control of when task-switches occur. The disadvantage to this
form of multi-tasking is that a task must request a task switch often if
the other tasks are to receive their chance to execute. If a task does
not request a task switch for a long time, the other tasks will appear
to pause. What's worse, if a task crashes, it won't be able to call the
operating system to let the other tasks execute, so they'll all be hung
too.
MTASK implements a very simple method of non-preemptive multi-tasking
that I call "request driven." Request driven means that task switches
occur only when the current task calls MTASK and requests a switch.
(The sole exception is that a task switch occurs when the current task
terminates itself). This is about the simplest form of multi-tasking
that I can envision. It is so simple that the entire MTASK unit
compiles to only about 1400 bytes with stack checking and range
checking turned off, or less if you don't use all of its procedures.
This simplicity also made MTASK easy to write and debug. MTASK was
written in one day!
1.2 WHAT ARE MTASK'S LIMITS?
MTASK allows your program to set up multiple tasks within itself.
These tasks will execute concurrently. However, it does not effect
anything outside of your program. It does not allow you to run
multiple programs, multiple copies of COMMAND.COM, or anything else
like that. It simply allows your program to do several things
concurrently without stumbling over itself.
As far as DOS is concerned, your program using MTASK is still just a
simple program. All of the gymnastics to keep track of multiple tasks
are done by MTASK, withing your program, without the knowledge or
consent of DOS or anything else outside of your program. Because MTASK
is so simple, it will coexist fine with any "real" multi-tasking DOS
you have set up, such as DesqView or Double-DOS. Whenever the DOS
gives your program some time, your program will dole out that time to
its tasks.
Your program must continue to execute for its tasks to execute. If any
task in your program exits to DOS for any reason, including a run-time
error, all tasks stop executing. If one of your tasks shells out by
using Turbo's Exec function, then the other tasks in your program are
suspended until control returns from the Exec function to your program.
MTASK must not be made into an overlay. Any of the tasks it controls
may be overlays, although that may be unwise. You could end up loading
an overlay from disk during each task switch!
2.1 SUMMARY OF PROCEDURES AND FUNCTIONS
To use MTASK, include it in your program's USES statements. MTASK will
initialize itself automatically, making your main program task #1.
Your program can then use the following procedures and functions to
create and control tasks:
create_task Create another task
terminate_task Destroy a task
switch_task Switch to another task
current_task_id Return the task ID of the current task
number_of_tasks Return the current number of tasks
2.1.1 PROCEDURE CREATE_TASK
PROCEDURE create_task
(
task : task_proc;
VAR param ;
stack_size: Word;
VAR id : Word;
VAR result: Word
);
TASK is the procedure to make into a task. It must match type
task_proc, having a single variable as its parameter.
PARAM is the parameter to pass to new_task. It may be a variable
of any type, so long its what the task expects. For example, if
you pass a Word and the task expects a LongInt, the task will get
invalid data.
STACK_SIZE is the size of the new task's stack. A stack will be
allocated from the heap. The minimum stack size is 512 bytes, but
most tasks will need more.
ID is set to the task ID of the newly created task. If the task
is not created because of an error, then id is not set.
RESULT is the result code, which is set to one of these values:
0 No error, task created ok
heap_full Unable to allocate heap for the task's
stack
too_many_tasks Maximum number of tasks are already
running
The new task is created and added to the end of the task list. The new
task will be executed when the task before it calls switch_task.
2.1.2 PROCEDURE TERMINATE_TASK
PROCEDURE terminate_task (id: Word; VAR result: Word);
ID is the task id of the task you want to terminate. If ID = 0,
then the current task will be terminated.
RESULT is the result code, which is set to one of these values.
0 No error, task deleted ok
invalid_task_id There is no task with that ID number
The designated task will be removed from the task list. If its stack
was allocated from the heap, it is returned to the heap.
If the terminated task is the current task and there is another task in
the task list, a task switch occurs. On the other hand, if the
terminated task is the current task and there are no other tasks in the
task list, then the program exits to DOS.
A task may terminate itself by returning from its main procedure. For
example, when this task is executed, it will immediately display a
message and then terminate itself.
PROCEDURE task (VAR param);
BEGIN
Writeln ('We just started, but already we're terminating')
END;
2.1.3 PROCEDURE switch_task
PROCEDURE switch_task;
This procedure causes an immediate switch to the next task in the task
list. The